package com.vcredit.bird.service.base;

import java.io.IOException;

import com.vcredit.creditcat.redis.RedisServiceExt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import com.alibaba.dubbo.common.utils.StringUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import com.vcredit.creditcat.exception.RMCloudRequestException;
import com.vcredit.framework.annotation.Log;
import com.vcredit.framework.util.HttpRequest;
import com.vcredit.framework.util.JacksonUtil;

/**
 * 风控云外部接口 基础服务
 * 
 * @author
 *
 */
public abstract class RMCloudService {

	Logger logger = LoggerFactory.getLogger(RMCloudService.class);

	@Value("${rmcloud.api.tokenurl}")
	private String RMCloud_tokenUrl;

	@Autowired
	private RedisServiceExt redisService;

	private static final String RMCLOUD_PREFIX = "rm:RMCloud";
	protected static final String RMC_API_SUFFIX = "?accesstoken=";
	private static final long RMC_CACHE_TIME = 7200;// 默认缓存风控云Token 3600*2（两个小时）

	/**
	 * 获取风控云认证的accessToken
	 * 
	 * @return
	 * @throws RMCloudRequestException
	 */
	@Log
	public String getRMCloudToken(String cacheKey) throws RMCloudRequestException {

		String fullCacheKey = StringUtils.join(new String[] { RMCLOUD_PREFIX, "TOKEN", cacheKey }, "_");
		RMC_OAuthRespVo response = (RMC_OAuthRespVo) redisService.get(fullCacheKey);
		if (response != null && !response.getAccesstoken().isEmpty()) {
			return response.getAccesstoken();
		}
		// RMC_OAuthRespVo response = null;
		try {
			String result = HttpRequest.doGet(RMCloud_tokenUrl);
			response = JacksonUtil.Json2Obj(result, new TypeReference<RMC_OAuthRespVo>() {
			});
			if (null != response && !StringUtils.isBlank(response.getErrorCode())) {
				logger.error("getRMCloudToken RMCloudRequestException:", response.getErrorCode());
				throw new RMCloudRequestException(
						"Authentication RMCloud failed : [errorCode:" + response.getErrorCode() + "]");
			}
			redisService.put(fullCacheKey, response, RMC_CACHE_TIME);
			return response.getAccesstoken();
		} catch (IOException e) {
			logger.error("getRMCloudToken IOException:", e);
			e.printStackTrace();
			throw new RMCloudRequestException(e.getMessage());
		} catch (Exception e) {
			logger.error("getRMCloudToken Exception:", e);
			e.printStackTrace();
			throw new RMCloudRequestException(e.getMessage());
		}
	}

	/**
	 * 请求风控云接口数据
	 * 
	 * @param url
	 * @param cacheKey
	 * @param postData
	 * @return
	 * @throws RMCloudRequestException
	 */
	@Log
	public BirdResponse postRMCloudBirdData(String url, String cacheKey, String postData)
			throws RMCloudRequestException {
		try {
			String accessToken = this.getRMCloudToken(cacheKey);
			String accessUrl = StringUtils.join(new String[] { url, RMC_API_SUFFIX, accessToken });
			String result = HttpRequest.doJson(accessUrl, postData);
			RMC_BaseRespVo rmcResp = JacksonUtil.Json2Obj(result, new TypeReference<RMC_BaseRespVo>() {
			});
			if (StringUtils.isBlank(rmcResp.getErrorCode())) {
				BirdResponse birdResp = JacksonUtil.Json2Obj(rmcResp.getData(), new TypeReference<BirdResponse>() {
				});
				if ("还未做数据校验,返回结果暂赋空值".equals(birdResp.getDesc())) {
					throw new RMCloudRequestException("因内部原因，该接口暂时无法提供服务");
				}
				return birdResp;
			} else {
				throw new RMCloudRequestException(rmcResp.getErrorCode());
			}
		} catch (Exception ex) {
			throw new RMCloudRequestException(ex.getMessage());
		}
	}

	/**
	 * 请求风控云接口数据
	 * 
	 * @param url
	 * @param cacheKey
	 * @param postData
	 * @return
	 * @throws RMCloudRequestException
	 */
	@Log
	public RMC_BaseRespVo postRMCloudData(String url, String cacheKey, String postData)
			throws RMCloudRequestException {
		try {
			String accessToken = this.getRMCloudToken(cacheKey);
			String accessUrl = StringUtils.join(new String[] { url, RMC_API_SUFFIX, accessToken });
			String result = HttpRequest.doJson(accessUrl, postData,30);
			RMC_BaseRespVo rmcResp = JacksonUtil.Json2Obj(result, new TypeReference<RMC_BaseRespVo>() {
			});
			return rmcResp;
		} catch (Exception ex) {
			logger.error("postRMCloudData:url:" + url, ex);
			throw new RMCloudRequestException(ex.getMessage());
		}
	}
}
